/*
 * buffedlog.h
 *
 *  Created on: 2011-5-8
 *      Author: chenl
 */

#ifndef BUFFEDLOG_H_
#define BUFFEDLOG_H_

#include "logengine.h"
#include "logapi.h"
#include "logqueue.h"
#include "datetime.h"
#include "common_type.h"
#include "common_util.h"
#include "common_libnamespace.h"

#include <stdio.h>
#include <string.h>
#include <assert.h>

CHENLIB_NAMESPACE_BEGIN

template<class TYPE_LOGQUEUE, unsigned SOURCE_ID = 0>
class CBuffedLog : public CLogEngineBase
{
public:
	CBuffedLog(): logSource_(SOURCE_ID), pLogQueue_(NULL)
	{
		memset(szLogPrefix_, 0, sizeof(szLogPrefix_));
	}
	CBuffedLog(LogLevel logLevel, char* szLogPrefix, TYPE_LOGQUEUE* pLogQueue) : CLogEngineBase(logLevel), logSource_(SOURCE_ID), pLogQueue_(pLogQueue)
	{
		memcpy(szLogPrefix_, szLogPrefix, sizeof(szLogPrefix_));
	}
	virtual ~CBuffedLog()
	{

	}

	void SetParam(LogLevel logLevel, char* szLogPrefix, TYPE_LOGQUEUE* pLogQueue)
	{
		logLevel_ = logLevel;
		memcpy(szLogPrefix_, szLogPrefix, sizeof(szLogPrefix_));
		pLogQueue_ = pLogQueue;
	}

	virtual int32_t Initialize()
	{
		if (NULL == pLogQueue_)
		{
			return E_NULLPOINTER;
		}
		int32_t ret = SetLogPrefix(logSource_, szLogPrefix_);
		return ret;
	}

	virtual int32_t Uninitialize()
	{
		return S_OK;
	}

	virtual int32_t WriteLog(LogLevel enmLogLv, const char* cszFormat, ...)
	{
		assert(NULL != cszFormat);

		if (unlikely(NULL == cszFormat))
			return E_NULLPOINTER;

		if (enmLogLv < GetLogLevel())
		{
			return S_FALSE;
		}

		//獲取當前時間
		const CDateTime& now = CDateTime::CurrentDateTime();
		char szLog[enmMaxLogLen] = {0};
		unsigned len = sizeof(szLog);

		//寫入時間信息
		int32_t ret = now.ToString(szLog, len);
		if (0 > ret)
		{
			return E_INVALIDARG;
		}

		//寫入日誌等級
		DECLARE_LOGLEVEL_STR(arrLogLevelStr);
		snprintf(szLog + len, sizeof(szLog) - len, "%s", arrLogLevelStr[enmLogLv]);

		//寫入日誌内容
		va_list argp;
		va_start(argp, cszFormat);
		len += strlen(arrLogLevelStr[enmLogLv]);
		vsnprintf(szLog + len, sizeof(szLog) - len, cszFormat, argp);
		va_end(argp);

		//壓入日誌隊列
		return pLogQueue_->Push(logSource_, szLog, strlen(szLog));
	}

	void SetLogSource(LogSource logSource)
	{
		logSource_ = logSource;
	}

	LogSource GetLogSource() const
	{
		return logSource_;
	}

	int32_t SetLogPrefix(LogSource logSource, char *szLogPrefix)
	{
		return pLogQueue_->SetLogPrefix(logSource, szLogPrefix);
	}

	char* GetLogPrefix(LogSource logSource)
	{
		return pLogQueue_->GetLogPrefix(logSource);
	}
private:
	LogSource				logSource_;
	char					szLogPrefix_[enmMaxLogFileNameLen];
	TYPE_LOGQUEUE* 			pLogQueue_;
};

CHENLIB_NAMESPACE_END

#endif /* BUFFEDLOG_H_ */
